<template>
  <div class="select-picker" v-if="isVisible">
    <div class="select-picker-mask" @click="close"></div>
    <div class="select-picker-panel">
      <div class="select-right-charts">
        <div class="select-right-name" v-for="(item,index) in letterList" :key="index">
          <div @click="curScroll(item.list[0])">{{item.title}}</div>
        </div>
      </div>
      <div class="picker-con">
        <div class="select-picker-panel-top">
          <div class="picker-control">
            <div class="picker-cancel-btn" @click="close">取消</div>
            <div class="picker-center-con">
              <nut-textinput
                  class="my-input"
                  :has-border="false"
                  type="search"
                  v-model="searchVal"
                  placeholder="请输入专业搜索"
                  ref="myInput"
                  @keyup.enter="searchSubmit"
                  @input="clearData"
              />
            </div>
            <div class="picker-confirm-btn" @click="confirm">确定</div>
          </div>
        </div>
        <div class="select-picker-all" >
          <div class="select-picker-list" @touchstart="listenerTouchStart" @touchmove="listenerTouchMove" @touchend="listenerTouchEnd">
            <!--滚轮区域 start-->
            <div class="select-picker-roller" :style="rollerStyle">
              <div class="nut-picker-roller-item" :class="{'nut-picker-roller-item-hidden': isHidden(index + 1)}"
                   v-for="(item,index) in datares" :key="index" :style="setRollerStyle(index+1)">
                {{item}}
              </div>
            </div>
            <!--滚轮区域 end-->
            <!-- 高亮选中区域 start-->
            <div class="nut-picker-content">
              <div class="nut-picker-list-panel" ref="list"  :style="panelStyle">
                <div class="nut-picker-item" v-for="(item,index) in datares" :key="index">{{item}}</div>
              </div>
            </div>
            <!-- 高亮选中区域 end-->
            <div class="nut-picker-mask"></div>
            <div class="nut-picker-indicator"></div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import {AlphabeticOrder} from '@/utils/charChange'; //获取汉字首字母
import Animate from '@/utils/animate';
export default {
  name: "CellPicker",
  desc: "下拉选择组件",
  props: {
    isVisible:{type:Boolean,default:false},
    listData:{type:Array}, //示例[['计算机','美术','美容']]
  },
  data() {
    return {
      datares: [],
      rollerStyle:'transform: rotate3d(1, 0, 0, 10deg); transition: transform 1000ms cubic-bezier(0.19, 1, 0.22, 1) 0s',
      panelStyle:
          'transform: translate3d(0px, 0px, 0px); transition: transform 1000ms cubic-bezier(0.19, 1, 0.22, 1) 0s',
      rotation:10, //半径
      currIndex:0,//当前选择的第几个
      isInertial:false,//是否惯性滚动
      finger: {
        startY: 0,
        startTime: 0, // 开始滑动时间（单位：毫秒）
        currentMove: 0,//为了获取当前index
        prevMove: 0,
      },
      searchVal:'',//搜索内容
    };
  },
  watch:{
    isVisible:{ //监听的对象
      handler:function(newV){
        if(newV){
         this.searchVal ='';//清空数据this.listData[0]
          this.datares=this.changeData(this.listData[0])
          //初始化数据
          this.initData()
        }
      },
      immediate:true,
    }
  },
  computed: {
    animate: () => (new Animate()),
    letterList(){
      //字母数组
      let letterList =AlphabeticOrder(this.datares)
      this.datares=[]
      letterList.forEach(item=>{
        item.list.forEach(item2=>{
          this.datares.push(item2)
        })
      })
      return letterList
    },
  },
  methods: {
    searchSubmit(){
      let datas = []
      if(this.listData[0]){
        let listData = this.changeData(this.listData[0])
        listData.map(item=>{
          if(item.indexOf(this.searchVal)!=-1){
            datas.push(item)
          }
        })
        this.datares = datas;
        this.initData()
      }
    },
    clearData(){
      //搜索栏清空后数据处理
      if(!this.searchVal){
        this.datares=this.changeData(this.listData[0])
        this.initData()
      }
    },
    confirm(){
      this.close();
      this.$emit('confirm',[this.datares[this.currIndex]])
    },
    curScroll(valId){
      this.datares.forEach((item,index)=>{
        if(valId===item){
          this.rollerStyle =`transform: rotate3d(1, 0, 0, ${(index+1)*10}deg); transition: transform 1000ms cubic-bezier(0.19, 1, 0.22, 1) 0s`
          this.panelStyle=`transform: translate3d(0px, ${index*-36}px, 0px); transition: transform 1000ms cubic-bezier(0.19, 1, 0.22, 1) 0s;`
          this.currIndex = index
          this.finger={
            startY: 0,
            startTime: 0, // 开始滑动时间（单位：毫秒）
            currentMove: (index+1)*36,//为了获取当前index
            prevMove: (index+1)*36,
          }//点击后初始化数据
        }
      })
    },

    setRollerStyle(index) {
    //动态设置滚轮项的最终位置。
      return`transform: rotate3d(1, 0, 0, ${-this.rotation * index}deg) translate3d(0px, 0px, 200px)`;
    },
    isHidden(index) {
      //我们需要把超出的部分隐藏掉，我们知道角度值 a 是10度，圆的一周是360度，所以最多可以显示36个，我们以当前中心为基础点，前面展示17个，后面展示18个。
      return(index >= this.currIndex + 17|| index <= this.currIndex - 18) ? true: false;
    },
    listenerTouchStart(ev){
      //滚动开始
      ev.stopPropagation(); ev.preventDefault();
      this.isInertial = false; // 初始状态没有惯性滚动
      this.finger.startY = ev.targetTouches[0].pageY; // 获取手指开始点击的位置
      this.finger.prevMove = this.finger.currentMove;
      this.finger.startTime = Date.now(); //开始时间
    },
    listenerTouchMove(ev){
      //滚动中
      ev.stopPropagation(); ev.preventDefault();
      this.finger.currentMove = (this.finger.startY - ev.targetTouches[0].pageY) + this.finger.prevMove;
      this.rollerStyle = `transform: rotate3d(1, 0, 0, ${(this.finger.currentMove/36) * 10}deg)`;
      this.panelStyle = `transform: translate3d(0px, ${((this.finger.currentMove/36)-1)*-36}px, 0px)`;
    },

    listenerTouchEnd(ev){
      //滚动结束
      ev.stopPropagation(); ev.preventDefault();
      const _endY = ev.changedTouches[0].pageY;
      const _entTime = Date.now();
      const v = (this.finger.startY - _endY)/ (_entTime - this.finger.startTime);// 滚动完毕求移动速度 v = (s初始-s结束) / t
      const absV = Math.abs(v);
      this.isInertial = true;// 最好惯性滚动,才不会死板aqqqqqqa
      this.inertia(absV, Math.round(absV / v), 0);// Math.round(absV / v)=>+/-1
    },
    inertia(start, position, target) {
      let a = -0.003 // 加速度
      let lineHeight =36//高度
      let singleDeg = 10;//滚动角度
      let isInertial = this.isInertial
      if (start <= target || !isInertial) {
        this.animate.stop();
        this.finger.prevMove = this.finger.currentMove;
        this.getSelectValue(this.finger.currentMove);// 得到选中的当前下标
        return;
      }
      const minIdx = 0;
      const maxIdx = this.datares.length;
      const freshTime = 1000 / 60;// 动画帧刷新的频率大概是1000 / 60
      // 这段时间走的位移 S = vt + 1/2at^2 + s1;
      const move = (position * start * freshTime) + (0.5 * a * Math.pow(freshTime,2)) + this.finger.currentMove;
      const newStart = (position * start) + (a * freshTime);// 根据求末速度公式： v末 = (+/-)v初 + at
      let actualMove = move; // 最后的滚动距离
      let moveDeg = 10 //正常的滚动角度
      let panelPx= 0//
      this.rollerStyle = '';
      this.panelStyle='';
      moveDeg = Math.round(move / lineHeight) * singleDeg;// 正常的滚动角度
      panelPx = (Math.round(move / lineHeight)-1) * -36;
      // 已经到达目标
      if (newStart <= target) {
        // 让滚动在文字区域内,超出区域的滚回到边缘的第一个文本处
        if(Math.round(move / lineHeight) <= minIdx) {
          moveDeg = minIdx>0?minIdx*singleDeg:singleDeg
          actualMove =minIdx>0?minIdx*lineHeight:lineHeight;
          panelPx =minIdx>0?(minIdx-1)*lineHeight:0
        }else if(Math.round(move / lineHeight) > maxIdx) {
          moveDeg = maxIdx*singleDeg;
          actualMove = maxIdx*lineHeight;
          panelPx =-(maxIdx-1)*lineHeight;
        }
      }
      //this.finger.currentMove赋值是为了点击确认的时候可以使用=>获取选中的值
      this.finger.currentMove = actualMove;
      this.rollerStyle =`transform: rotate3d(1, 0, 0, ${moveDeg}deg); transition: transform 1000ms cubic-bezier(0.19, 1, 0.22, 1) 0s`
      this.panelStyle=`transform: translate3d(0px, ${panelPx}px, 0px); transition: transform 1000ms cubic-bezier(0.19, 1, 0.22, 1) 0s;`
      this.animate.start(this.inertia.bind(this, newStart, position, target));
    },
    getSelectValue(move) { this.currIndex = Math.round(move / 36)-1 >0 ?Math.round(move / 36)-1 :0;},

    initData(){
      // 初始化数据
      this.rollerStyle =`transform: rotate3d(1, 0, 0, 10deg); transition: transform 1000ms cubic-bezier(0.19, 1, 0.22, 1) 0s`
      this.panelStyle=`transform: translate3d(0px, 0px, 0px); transition: transform 1000ms cubic-bezier(0.19, 1, 0.22, 1) 0s;`
      this.finger={
        startY: 0,
        startTime: 0, // 开始滑动时间（单位：毫秒）
        currentMove: 0,//为了获取当前index
        prevMove: 0,
      }
      this.currIndex=0
    },
    //字符串中包含、号的重新计算
    changeData(data){
      let datasList=[]
      data.forEach(item=>{
        if(item.indexOf('、')>-1){
          item.split('、').forEach(item2=>{
            datasList.push(item2)
          })
        }else {
          datasList.push(item)
        }
      })
      return [...new Set(datasList)]
    },
    close(){
      this.$emit('close')
    },

  },
};
</script>
<style lang="scss" scoped>
/deep/.nut-textinput input{
  height: 30px;
  text-align: center;
  padding:0 30px 0 10px;
  margin: 5px 0px;
  background: #f3f3f3;
  border-radius: 30px;
}
.select-picker {
  .select-picker-mask {
    position: fixed;
    z-index: 9998;
    top: 0;
    right: 0;
    left: 0;
    bottom: 0;
    background-color: rgba(0, 0, 0, 0.5);
  }
  .select-picker-panel-top{
    height: 40px;
    border-bottom: 1px solid #f6f6f6;
    margin-bottom:10px;
    .picker-control{
      display: flex;
      text-align: center;
      line-height: 40px;
      .picker-cancel-btn{
        width: 60px;
        color: #bebebe;
      }
      .picker-center-con{
        flex: 1;
      }
      .picker-confirm-btn{
        width: 60px;
        color: #4D73E2;
      }
    }
  }
  .select-picker-panel {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    width: 100%;
    max-height: 80%;
    overflow: auto;
    z-index: 10001;
    background-color: #f6f6f6;
    .picker-con {
      background-color: #fff;
      width: 100%;
      .select-picker-all {
        height: 380px;
        display: flex;
        .select-picker-list {
          flex: 1;
          position: relative;
          height: 380px;
          overflow: hidden;
          .select-picker-roller {
            position: absolute;
            top: 140px;
            width: 100%;
            height: 36px;
            transform-style: preserve-3d;
            z-index: 1;
            .nut-picker-roller-item {
              backface-visibility: hidden;
              position: absolute;
              top: 0;
              width: 100%;
              color: #848484;
              white-space: nowrap;
              overflow: hidden;
              -o-text-overflow: ellipsis;
              text-overflow: ellipsis;
              height: 36px;
              line-height: 36px;
              font-size: 14px;
              text-align: center;
              padding-right: 30px;
            }
            .nut-picker-roller-item-hidden{
              visibility: hidden;
              opacity: 0;
            }
          }
          .nut-picker-content {
            background: #fff;
            z-index: 2;
            overflow: hidden;
            position: absolute;
            top: 140px;
            width: 100%;
            height: 36px;
            .nut-picker-list-panel {
              transform-style: preserve-3d;
              .nut-picker-item {
                background: #fff;
                white-space: nowrap;
                overflow: hidden;
                -o-text-overflow: ellipsis;
                text-overflow: ellipsis;
                height: 36px;
                line-height: 36px;
                color: #2d2d2d;
                font-size: 14px;
                text-align: center;
                padding-right: 30px;
              }
            }
          }

          .nut-picker-mask {
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-position: top, bottom;
            background-size: 100% 140px;
            background-repeat: no-repeat;
            z-index: 3;
          }
          .nut-picker-indicator {
            position: absolute;
            top: 140px;
            width: 100%;
            height: 36px;
            border-top: 1px solid #dadada;
            border-bottom: 1px solid #dadada;
            z-index: 3;
          }
        }
      }
    }
  }
  .select-right-charts{
    position: absolute;
    right: 20px;
    z-index: 10000;
    top: 50%;
    transform: translateY(-50%);
    margin-top: 20px;
    .select-right-name{
      width: 40px;
      height: 18px;
      line-height: 18px;
      text-align: center;
      //background: #fff;
    }
  }
}

</style>